package core.util;

import java.io.IOException;
import java.io.Writer;
import java.lang.reflect.Method;
import java.util.Map;

import org.apache.shiro.SecurityUtils;

import freemarker.core.Environment;
import freemarker.template.SimpleScalar;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;

public class ShiroTag implements TemplateDirectiveModel {

	public final static String hasPermission = "hasPermission";
	public final static String principal = "principal";
	public final static String[] keys = { hasPermission, principal };

	@Override
	public void execute(Environment env, @SuppressWarnings("rawtypes") Map params, TemplateModel[] loopVars,
			TemplateDirectiveBody body) throws TemplateException, IOException {
		for (String key : keys) {
			if (params.containsKey(key)) {
				String value = ((SimpleScalar) params.get(key)).getAsString();
				switch (key) {
				case hasPermission:
					hasPermission(value, env, body);
					return;
				case principal:
					principal(value, env, body);
					return;
				default:
					break;
				}
				break;
			}
		}
		if (body != null) {
			body.render(env.getOut());
		}
	}
	
	/**
	 * 反射IPrincipal的与参数的get方法匹配的方法并调用获取值渲染
	 * @param value
	 * @param env
	 * @param body
	 * @throws TemplateException
	 * @throws IOException
	 */
	public static void principal(String value, Environment env, TemplateDirectiveBody body)
			throws TemplateException, IOException {
		Writer writer = env.getOut();
		IPrincipal principal = (IPrincipal) SecurityUtils.getSubject().getPrincipal();
		Method[] m = IPrincipal.class.getMethods();
		for (Method method : m) {
			if (method.getName().equalsIgnoreCase("get" + value)) {
				try {
					Object obj = method.invoke(principal);
					writer.append(obj.toString());
					return;
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

	public static void hasPermission(String value, Environment env, TemplateDirectiveBody body)
			throws TemplateException, IOException {
		if (SecurityUtils.getSubject().isPermitted(value)) {
			body.render(env.getOut());
		}
	}
}
